
<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_CN">
  <head>
    <meta charset="utf-8" />
    <title>扩展/嵌入常见问题 &#8212; Python 3.7.8 文档</title>
    <link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    
    <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
    <script type="text/javascript" src="../_static/jquery.js"></script>
    <script type="text/javascript" src="../_static/underscore.js"></script>
    <script type="text/javascript" src="../_static/doctools.js"></script>
    <script type="text/javascript" src="../_static/language_data.js"></script>
    <script type="text/javascript" src="../_static/translations.js"></script>
    
    <script type="text/javascript" src="../_static/sidebar.js"></script>
    
    <link rel="search" type="application/opensearchdescription+xml"
          title="在 Python 3.7.8 文档 中搜索"
          href="../_static/opensearch.xml"/>
    <link rel="author" title="关于这些文档" href="../about.html" />
    <link rel="index" title="索引" href="../genindex.html" />
    <link rel="search" title="搜索" href="../search.html" />
    <link rel="copyright" title="版权所有" href="../copyright.html" />
    <link rel="next" title="Python在Windows上的常见问题" href="windows.html" />
    <link rel="prev" title="代码库和插件 FAQ" href="library.html" />
    <link rel="shortcut icon" type="image/png" href="../_static/py.png" />
    <link rel="canonical" href="https://docs.python.org/3/faq/extending.html" />
    
    <script type="text/javascript" src="../_static/copybutton.js"></script>
    
    
    
    
    <style>
      @media only screen {
        table.full-width-table {
            width: 100%;
        }
      }
    </style>
 

  </head><body>
  
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>导航</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="总目录"
             accesskey="I">索引</a></li>
        <li class="right" >
          <a href="../py-modindex.html" title="Python 模块索引"
             >模块</a> |</li>
        <li class="right" >
          <a href="windows.html" title="Python在Windows上的常见问题"
             accesskey="N">下一页</a> |</li>
        <li class="right" >
          <a href="library.html" title="代码库和插件 FAQ"
             accesskey="P">上一页</a> |</li>
        <li><img src="../_static/py.png" alt=""
                 style="vertical-align: middle; margin-top: -1px"/></li>
        <li><a href="https://www.python.org/">Python</a> &#187;</li>
        <li>
          <a href="../index.html">3.7.8 Documentation</a> &#187;
        </li>

          <li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python 常见问题</a> &#187;</li>
    <li class="right">
        

    <div class="inline-search" style="display: none" role="search">
        <form class="inline-search" action="../search.html" method="get">
          <input placeholder="快速搜索" type="text" name="q" />
          <input type="submit" value="转向" />
          <input type="hidden" name="check_keywords" value="yes" />
          <input type="hidden" name="area" value="default" />
        </form>
    </div>
    <script type="text/javascript">$('.inline-search').show(0);</script>
         |
    </li>

      </ul>
    </div>    

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body" role="main">
            
  <div class="section" id="extending-embedding-faq">
<h1><a class="toc-backref" href="#id3">扩展/嵌入常见问题</a><a class="headerlink" href="#extending-embedding-faq" title="永久链接至标题">¶</a></h1>
<div class="contents topic" id="id1">
<p class="topic-title">目录</p>
<ul class="simple">
<li><p><a class="reference internal" href="#extending-embedding-faq" id="id3">扩展/嵌入常见问题</a></p>
<ul>
<li><p><a class="reference internal" href="#can-i-create-my-own-functions-in-c" id="id4">可以使用C语言中创建自己的函数吗？</a></p></li>
<li><p><a class="reference internal" href="#id2" id="id5">可以使用C++语言中创建自己的函数吗？</a></p></li>
<li><p><a class="reference internal" href="#writing-c-is-hard-are-there-any-alternatives" id="id6">C很难写，有没有其他选择？</a></p></li>
<li><p><a class="reference internal" href="#how-can-i-execute-arbitrary-python-statements-from-c" id="id7">如何在 C 中执行任意 Python 语句？</a></p></li>
<li><p><a class="reference internal" href="#how-can-i-evaluate-an-arbitrary-python-expression-from-c" id="id8">如何在 C 中对任意 Python 表达式求值？</a></p></li>
<li><p><a class="reference internal" href="#how-do-i-extract-c-values-from-a-python-object" id="id9">如何从Python对象中提取C的值？</a></p></li>
<li><p><a class="reference internal" href="#how-do-i-use-py-buildvalue-to-create-a-tuple-of-arbitrary-length" id="id10">如何使用Py_BuildValue()创建任意长度的元组？</a></p></li>
<li><p><a class="reference internal" href="#how-do-i-call-an-object-s-method-from-c" id="id11">如何从C调用对象的方法？</a></p></li>
<li><p><a class="reference internal" href="#how-do-i-catch-the-output-from-pyerr-print-or-anything-that-prints-to-stdout-stderr" id="id12">如何捕获PyErr_Print()（或打印到stdout / stderr的任何内容）的输出？</a></p></li>
<li><p><a class="reference internal" href="#how-do-i-access-a-module-written-in-python-from-c" id="id13">如何从C访问用Python编写的模块？</a></p></li>
<li><p><a class="reference internal" href="#how-do-i-interface-to-c-objects-from-python" id="id14">如何在 Python 中对接 C ++ 对象？</a></p></li>
<li><p><a class="reference internal" href="#i-added-a-module-using-the-setup-file-and-the-make-fails-why" id="id15">我使用Setup文件添加了一个模块，为什么make失败了？</a></p></li>
<li><p><a class="reference internal" href="#how-do-i-debug-an-extension" id="id16">如何调试扩展？</a></p></li>
<li><p><a class="reference internal" href="#i-want-to-compile-a-python-module-on-my-linux-system-but-some-files-are-missing-why" id="id17">我想在Linux系统上编译一个Python模块，但是缺少一些文件。为什么?</a></p></li>
<li><p><a class="reference internal" href="#how-do-i-tell-incomplete-input-from-invalid-input" id="id18">如何区分“输入不完整”和“输入无效”？</a></p></li>
<li><p><a class="reference internal" href="#how-do-i-find-undefined-g-symbols-builtin-new-or-pure-virtual" id="id19">如何找到未定义的g++符号__builtin_new或__pure_virtual？</a></p></li>
<li><p><a class="reference internal" href="#can-i-create-an-object-class-with-some-methods-implemented-in-c-and-others-in-python-e-g-through-inheritance" id="id20">能否创建一个对象类，其中部分方法在C中实现，而其他方法在Python中实现（例如通过继承）？</a></p></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="can-i-create-my-own-functions-in-c">
<h2><a class="toc-backref" href="#id4">可以使用C语言中创建自己的函数吗？</a><a class="headerlink" href="#can-i-create-my-own-functions-in-c" title="永久链接至标题">¶</a></h2>
<p>是的，您可以在C中创建包含函数、变量、异常甚至新类型的内置模块。在文档 <a class="reference internal" href="../extending/index.html#extending-index"><span class="std std-ref">扩展和嵌入 Python 解释器</span></a> 中有说明。</p>
<p>大多数中级或高级的Python书籍也涵盖这个主题。</p>
</div>
<div class="section" id="id2">
<h2><a class="toc-backref" href="#id5">可以使用C++语言中创建自己的函数吗？</a><a class="headerlink" href="#id2" title="永久链接至标题">¶</a></h2>
<p>是的，可以使用C ++中兼容C的功能。 在Python include文件周围放置` <cite>extern“C”{...}`</cite> ，并在Python解释器调用的每个函数之前放置 <code class="docutils literal notranslate"><span class="pre">extern“C”</span></code> 。 具有构造函数的全局或静态C ++对象可能不是一个好主意。</p>
</div>
<div class="section" id="writing-c-is-hard-are-there-any-alternatives">
<span id="c-wrapper-software"></span><h2><a class="toc-backref" href="#id6">C很难写，有没有其他选择？</a><a class="headerlink" href="#writing-c-is-hard-are-there-any-alternatives" title="永久链接至标题">¶</a></h2>
<p>编写自己的C扩展有很多选择，具体取决于您要做的事情。</p>
<p><a class="reference external" href="http://cython.org">Cython</a> 及其相关的 <a class="reference external" href="https://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/">Pyrex</a> 是接受稍微修改过的Python形式并生成相应C代码的编译器。 Cython和Pyrex可以编写扩展而无需学习Python的C API。</p>
<p>如果需要连接到某些当前不存在Python扩展的C或C ++库，可以尝试使用 <a class="reference external" href="http://www.swig.org">SWIG</a> 等工具包装库的数据类型和函数。  <a class="reference external" href="https://riverbankcomputing.com/software/sip/intro">SIP</a> ， <a class="reference external" href="http://cxx.sourceforge.net/">CXX</a> <a class="reference external" href="http://www.boost.org/libs/python/doc/index.html">Boost</a> , 或 <a class="reference external" href="https://github.com/scipy/weave">Weave</a> 也是包装C ++库的替代方案。</p>
</div>
<div class="section" id="how-can-i-execute-arbitrary-python-statements-from-c">
<h2><a class="toc-backref" href="#id7">如何在 C 中执行任意 Python 语句？</a><a class="headerlink" href="#how-can-i-execute-arbitrary-python-statements-from-c" title="永久链接至标题">¶</a></h2>
<p>执行此操作的最高层级函数为 <a class="reference internal" href="../c-api/veryhigh.html#c.PyRun_SimpleString" title="PyRun_SimpleString"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyRun_SimpleString()</span></code></a>，它接受单个字符串参数用于在模块 <code class="docutils literal notranslate"><span class="pre">__main__</span></code> 的上下文中执行并在成功时返回 <code class="docutils literal notranslate"><span class="pre">0</span></code> 而在发生异常 (包括 <a class="reference internal" href="../library/exceptions.html#SyntaxError" title="SyntaxError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SyntaxError</span></code></a>) 时返回 <code class="docutils literal notranslate"><span class="pre">-1</span></code>。 如果你想要更多可控性，可以使用 <a class="reference internal" href="../c-api/veryhigh.html#c.PyRun_String" title="PyRun_String"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyRun_String()</span></code></a>；请在 <code class="docutils literal notranslate"><span class="pre">Python/pythonrun.c</span></code> 中查看 <a class="reference internal" href="../c-api/veryhigh.html#c.PyRun_SimpleString" title="PyRun_SimpleString"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyRun_SimpleString()</span></code></a> 的源码。</p>
</div>
<div class="section" id="how-can-i-evaluate-an-arbitrary-python-expression-from-c">
<h2><a class="toc-backref" href="#id8">如何在 C 中对任意 Python 表达式求值？</a><a class="headerlink" href="#how-can-i-evaluate-an-arbitrary-python-expression-from-c" title="永久链接至标题">¶</a></h2>
<p>可以调用前一问题中介绍的函数 <a class="reference internal" href="../c-api/veryhigh.html#c.PyRun_String" title="PyRun_String"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyRun_String()</span></code></a> 并附带起始标记符 <a class="reference internal" href="../c-api/veryhigh.html#c.Py_eval_input" title="Py_eval_input"><code class="xref c c-data docutils literal notranslate"><span class="pre">Py_eval_input</span></code></a>；它会解析表达式，对其求值并返回结果值。</p>
</div>
<div class="section" id="how-do-i-extract-c-values-from-a-python-object">
<h2><a class="toc-backref" href="#id9">如何从Python对象中提取C的值？</a><a class="headerlink" href="#how-do-i-extract-c-values-from-a-python-object" title="永久链接至标题">¶</a></h2>
<p>这取决于对象的类型。 如果是元组，<a class="reference internal" href="../c-api/tuple.html#c.PyTuple_Size" title="PyTuple_Size"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyTuple_Size()</span></code></a> 可返回其长度而 <a class="reference internal" href="../c-api/tuple.html#c.PyTuple_GetItem" title="PyTuple_GetItem"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyTuple_GetItem()</span></code></a> 可返回指定序号上的项。 对于列表也有类似的函数 <code class="xref c c-func docutils literal notranslate"><span class="pre">PyListSize()</span></code> 和 <a class="reference internal" href="../c-api/list.html#c.PyList_GetItem" title="PyList_GetItem"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyList_GetItem()</span></code></a>。</p>
<p>对于字节串，<a class="reference internal" href="../c-api/bytes.html#c.PyBytes_Size" title="PyBytes_Size"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyBytes_Size()</span></code></a> 可返回其长度而 <a class="reference internal" href="../c-api/bytes.html#c.PyBytes_AsStringAndSize" title="PyBytes_AsStringAndSize"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyBytes_AsStringAndSize()</span></code></a> 提供一个指向其值和长度的指针。 请注意 Python 字节串可能为空，因此 C 的 <code class="xref c c-func docutils literal notranslate"><span class="pre">strlen()</span></code> 不应被使用。</p>
<p>要检测一个对象的类型，首先要确保它不为 <code class="docutils literal notranslate"><span class="pre">NULL</span></code>，然后使用 <a class="reference internal" href="../c-api/bytes.html#c.PyBytes_Check" title="PyBytes_Check"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyBytes_Check()</span></code></a>, <a class="reference internal" href="../c-api/tuple.html#c.PyTuple_Check" title="PyTuple_Check"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyTuple_Check()</span></code></a>, <a class="reference internal" href="../c-api/list.html#c.PyList_Check" title="PyList_Check"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyList_Check()</span></code></a> 等等。</p>
<p>还有一个针对 Python 对象的高层级 API，通过所谓的‘抽象’接口提供 —— 请参阅 <code class="docutils literal notranslate"><span class="pre">Include/abstract.h</span></code> 了解详情。 它允许使用 <a class="reference internal" href="../c-api/sequence.html#c.PySequence_Length" title="PySequence_Length"><code class="xref c c-func docutils literal notranslate"><span class="pre">PySequence_Length()</span></code></a>, <a class="reference internal" href="../c-api/sequence.html#c.PySequence_GetItem" title="PySequence_GetItem"><code class="xref c c-func docutils literal notranslate"><span class="pre">PySequence_GetItem()</span></code></a> 这样的调用来与任意种类的 Python 序列进行对接，此外还可使用许多其他有用的协议例如数字 (<a class="reference internal" href="../c-api/number.html#c.PyNumber_Index" title="PyNumber_Index"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyNumber_Index()</span></code></a> 等) 以及 PyMapping API 中的各种映射等等。</p>
</div>
<div class="section" id="how-do-i-use-py-buildvalue-to-create-a-tuple-of-arbitrary-length">
<h2><a class="toc-backref" href="#id10">如何使用Py_BuildValue()创建任意长度的元组？</a><a class="headerlink" href="#how-do-i-use-py-buildvalue-to-create-a-tuple-of-arbitrary-length" title="永久链接至标题">¶</a></h2>
<p>不可以。应该使用 <a class="reference internal" href="../c-api/tuple.html#c.PyTuple_Pack" title="PyTuple_Pack"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyTuple_Pack()</span></code></a> 。</p>
</div>
<div class="section" id="how-do-i-call-an-object-s-method-from-c">
<h2><a class="toc-backref" href="#id11">如何从C调用对象的方法？</a><a class="headerlink" href="#how-do-i-call-an-object-s-method-from-c" title="永久链接至标题">¶</a></h2>
<p>可以使用 <a class="reference internal" href="../c-api/object.html#c.PyObject_CallMethod" title="PyObject_CallMethod"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_CallMethod()</span></code></a> 函数来调用某个对象的任意方法。 形参为该对象、要调用的方法名、类似 <a class="reference internal" href="../c-api/arg.html#c.Py_BuildValue" title="Py_BuildValue"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_BuildValue()</span></code></a> 所用的格式字符串以及要传给方法的参数值:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">PyObject</span> <span class="o">*</span>
<span class="nf">PyObject_CallMethod</span><span class="p">(</span><span class="n">PyObject</span> <span class="o">*</span><span class="n">object</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">method_name</span><span class="p">,</span>
                    <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">arg_format</span><span class="p">,</span> <span class="p">...);</span>
</pre></div>
</div>
<p>这适用于任何具有方法的对象 —— 不论是内置方法还是用户自定义方法。 你需要负责对返回值进行最终的 <a class="reference internal" href="../c-api/refcounting.html#c.Py_DECREF" title="Py_DECREF"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_DECREF()</span></code></a> 处理。</p>
<p>例如调用某个文件对象的 &quot;seek&quot; 方法并传入参数 10, 0 (假定文件对象的指针为 &quot;f&quot;):</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">res</span> <span class="o">=</span> <span class="n">PyObject_CallMethod</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="s">&quot;seek&quot;</span><span class="p">,</span> <span class="s">&quot;(ii)&quot;</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">res</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span> <span class="p">{</span>
        <span class="p">...</span> <span class="n">an</span> <span class="n">exception</span> <span class="n">occurred</span> <span class="p">...</span>
<span class="p">}</span>
<span class="k">else</span> <span class="p">{</span>
        <span class="n">Py_DECREF</span><span class="p">(</span><span class="n">res</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
<p>请注意由于 <a class="reference internal" href="../c-api/object.html#c.PyObject_CallObject" title="PyObject_CallObject"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_CallObject()</span></code></a> <em>总是</em> 接受一个元组作为参数列表，要调用不带参数的函数，则传入格式为 &quot;()&quot;，要调用只带一个参数的函数，则应将参数包含于圆括号中，例如 &quot;(i)&quot;。</p>
</div>
<div class="section" id="how-do-i-catch-the-output-from-pyerr-print-or-anything-that-prints-to-stdout-stderr">
<h2><a class="toc-backref" href="#id12">如何捕获PyErr_Print()（或打印到stdout / stderr的任何内容）的输出？</a><a class="headerlink" href="#how-do-i-catch-the-output-from-pyerr-print-or-anything-that-prints-to-stdout-stderr" title="永久链接至标题">¶</a></h2>
<p>在 Python 代码中，定义一个支持 <code class="docutils literal notranslate"><span class="pre">write()</span></code> 方法的对象。 将此对象赋值给 <a class="reference internal" href="../library/sys.html#sys.stdout" title="sys.stdout"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.stdout</span></code></a> 和 <a class="reference internal" href="../library/sys.html#sys.stderr" title="sys.stderr"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.stderr</span></code></a>。 调用 print_error 或者只是允许标准回溯机制生效。 在此之后，输出将转往你的 <code class="docutils literal notranslate"><span class="pre">write()</span></code> 方法所指向的任何地方。</p>
<p>做到这一点的最简单方式是使用 <a class="reference internal" href="../library/io.html#io.StringIO" title="io.StringIO"><code class="xref py py-class docutils literal notranslate"><span class="pre">io.StringIO</span></code></a> 类：</p>
<div class="highlight-pycon notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">io</span><span class="o">,</span> <span class="nn">sys</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">stdout</span> <span class="o">=</span> <span class="n">io</span><span class="o">.</span><span class="n">StringIO</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="s1">&#39;foo&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="s1">&#39;hello world!&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">getvalue</span><span class="p">())</span>
<span class="go">foo</span>
<span class="go">hello world!</span>
</pre></div>
</div>
<p>实现同样效果的自定义对象看起来是这样的：</p>
<div class="highlight-pycon notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">io</span><span class="o">,</span> <span class="nn">sys</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">StdoutCatcher</span><span class="p">(</span><span class="n">io</span><span class="o">.</span><span class="n">TextIOBase</span><span class="p">):</span>
<span class="gp">... </span>    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="gp">... </span>        <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="p">[]</span>
<span class="gp">... </span>    <span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">stuff</span><span class="p">):</span>
<span class="gp">... </span>        <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">stuff</span><span class="p">)</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">sys</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">stdout</span> <span class="o">=</span> <span class="n">StdoutCatcher</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="s1">&#39;foo&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="s1">&#39;hello world!&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">data</span><span class="p">))</span>
<span class="go">foo</span>
<span class="go">hello world!</span>
</pre></div>
</div>
</div>
<div class="section" id="how-do-i-access-a-module-written-in-python-from-c">
<h2><a class="toc-backref" href="#id13">如何从C访问用Python编写的模块？</a><a class="headerlink" href="#how-do-i-access-a-module-written-in-python-from-c" title="永久链接至标题">¶</a></h2>
<p>你可以通过如下方式获得一个指向模块对象的指针:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">module</span> <span class="o">=</span> <span class="n">PyImport_ImportModule</span><span class="p">(</span><span class="s">&quot;&lt;modulename&gt;&quot;</span><span class="p">);</span>
</pre></div>
</div>
<p>如果模块尚未被导入（即它还不存在于 <a class="reference internal" href="../library/sys.html#sys.modules" title="sys.modules"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.modules</span></code></a> 中），这会初始化该模块；否则它只是简单地返回 <code class="docutils literal notranslate"><span class="pre">sys.modules[&quot;&lt;modulename&gt;&quot;]</span></code> 的值。 请注意它并不会将模块加入任何命名空间 —— 它只是确保模块被初始化并存在于 <a class="reference internal" href="../library/sys.html#sys.modules" title="sys.modules"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.modules</span></code></a> 中。</p>
<p>之后你就可以通过如下方式来访问模块的属性（即模块中定义的任何名称）:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">attr</span> <span class="o">=</span> <span class="n">PyObject_GetAttrString</span><span class="p">(</span><span class="n">module</span><span class="p">,</span> <span class="s">&quot;&lt;attrname&gt;&quot;</span><span class="p">);</span>
</pre></div>
</div>
<p>调用 <a class="reference internal" href="../c-api/object.html#c.PyObject_SetAttrString" title="PyObject_SetAttrString"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_SetAttrString()</span></code></a> 为模块中的变量赋值也是可以的。</p>
</div>
<div class="section" id="how-do-i-interface-to-c-objects-from-python">
<h2><a class="toc-backref" href="#id14">如何在 Python 中对接 C ++ 对象？</a><a class="headerlink" href="#how-do-i-interface-to-c-objects-from-python" title="永久链接至标题">¶</a></h2>
<p>根据你的需求，可以选择许多方式。 手动的实现方式请查阅 <a class="reference internal" href="../extending/index.html#extending-index"><span class="std std-ref">&quot;扩展与嵌入&quot; 文档</span></a> 来入门。 需要知道的是对于 Python 运行时系统来说，C 和 C++ 并不没有太大的区别 —— 因此围绕一个 C 结构（指针）类型构建新 Python 对象的策略同样适用于 C++ 对象。</p>
<p>有关C ++库，请参阅 <a class="reference internal" href="#c-wrapper-software"><span class="std std-ref">C很难写，有没有其他选择？</span></a></p>
</div>
<div class="section" id="i-added-a-module-using-the-setup-file-and-the-make-fails-why">
<h2><a class="toc-backref" href="#id15">我使用Setup文件添加了一个模块，为什么make失败了？</a><a class="headerlink" href="#i-added-a-module-using-the-setup-file-and-the-make-fails-why" title="永久链接至标题">¶</a></h2>
<p>安装程序必须以换行符结束，如果没有换行符，则构建过程将失败。 （修复这个需要一些丑陋的shell脚本编程，而且这个bug很小，看起来不值得花这么大力气。)</p>
</div>
<div class="section" id="how-do-i-debug-an-extension">
<h2><a class="toc-backref" href="#id16">如何调试扩展？</a><a class="headerlink" href="#how-do-i-debug-an-extension" title="永久链接至标题">¶</a></h2>
<p>将GDB与动态加载的扩展名一起使用时，在加载扩展名之前，不能在扩展名中设置断点。</p>
<p>在您的 <code class="docutils literal notranslate"><span class="pre">.gdbinit</span></code> 文件中（或交互式）添加命令：</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>br _PyImport_LoadDynamicModule
</pre></div>
</div>
<p>然后运行GDB：</p>
<div class="highlight-shell-session notranslate"><div class="highlight"><pre><span></span><span class="gp">$</span> gdb /local/bin/python
<span class="go">gdb) run myscript.py</span>
<span class="go">gdb) continue # repeat until your extension is loaded</span>
<span class="go">gdb) finish   # so that your extension is loaded</span>
<span class="go">gdb) br myfunction.c:50</span>
<span class="go">gdb) continue</span>
</pre></div>
</div>
</div>
<div class="section" id="i-want-to-compile-a-python-module-on-my-linux-system-but-some-files-are-missing-why">
<h2><a class="toc-backref" href="#id17">我想在Linux系统上编译一个Python模块，但是缺少一些文件。为什么?</a><a class="headerlink" href="#i-want-to-compile-a-python-module-on-my-linux-system-but-some-files-are-missing-why" title="永久链接至标题">¶</a></h2>
<p>大多数打包的Python版本不包含 <code class="file docutils literal notranslate"><span class="pre">/usr/lib/python2.</span><em><span class="pre">x</span></em><span class="pre">/config/</span></code> 目录，该目录中包含编译Python扩展所需的各种文件。</p>
<p>对于Red Hat，安装python-devel RPM以获取必要的文件。</p>
<p>对于Debian，运行 <code class="docutils literal notranslate"><span class="pre">apt-get</span> <span class="pre">install</span> <span class="pre">python-dev</span></code> 。</p>
</div>
<div class="section" id="how-do-i-tell-incomplete-input-from-invalid-input">
<h2><a class="toc-backref" href="#id18">如何区分“输入不完整”和“输入无效”？</a><a class="headerlink" href="#how-do-i-tell-incomplete-input-from-invalid-input" title="永久链接至标题">¶</a></h2>
<p>有时，希望模仿Python交互式解释器的行为，在输入不完整时(例如，您键入了“if”语句的开头，或者没有关闭括号或三个字符串引号)，给出一个延续提示，但当输入无效时，立即给出一条语法错误消息。</p>
<p>在Python中，您可以使用 <a class="reference internal" href="../library/codeop.html#module-codeop" title="codeop: Compile (possibly incomplete) Python code."><code class="xref py py-mod docutils literal notranslate"><span class="pre">codeop</span></code></a> 模块，该模块非常接近解析器的行为。例如，IDLE就使用了这个。</p>
<p>在C中执行此操作的最简单方法是调用 <a class="reference internal" href="../c-api/veryhigh.html#c.PyRun_InteractiveLoop" title="PyRun_InteractiveLoop"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyRun_InteractiveLoop()</span></code></a> （可能在单独的线程中）并让Python解释器为您处理输入。您还可以设置 <a class="reference internal" href="../c-api/veryhigh.html#c.PyOS_ReadlineFunctionPointer" title="PyOS_ReadlineFunctionPointer"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyOS_ReadlineFunctionPointer()</span></code></a> 指向您的自定义输入函数。有关更多提示，请参阅 <code class="docutils literal notranslate"><span class="pre">Modules/readline.c</span></code> 和 <code class="docutils literal notranslate"><span class="pre">Parser/myreadline.c</span></code> 。</p>
<p>但是，有时必须在与其他应用程序相同的线程中运行嵌入式Python解释器，并且不能允许 <a class="reference internal" href="../c-api/veryhigh.html#c.PyRun_InteractiveLoop" title="PyRun_InteractiveLoop"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyRun_InteractiveLoop()</span></code></a> 在等待用户输入时停止。那么另一个解决方案是调用 <code class="xref c c-func docutils literal notranslate"><span class="pre">PyParser_ParseString()</span></code> 并测试 <code class="docutils literal notranslate"><span class="pre">e.error</span></code> 等于 <code class="docutils literal notranslate"><span class="pre">E_EOF</span></code> ，如果等于，就意味着输入不完整。这是一个示例代码片段，未经测试，灵感来自Alex Farber的代码:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#define PY_SSIZE_T_CLEAN</span>
<span class="cp">#include</span> <span class="cpf">&lt;Python.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;node.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;errcode.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;grammar.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;parsetok.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;compile.h&gt;</span><span class="cp"></span>

<span class="kt">int</span> <span class="nf">testcomplete</span><span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="n">code</span><span class="p">)</span>
  <span class="cm">/* code should end in \n */</span>
  <span class="cm">/* return -1 for error, 0 for incomplete, 1 for complete */</span>
<span class="p">{</span>
  <span class="n">node</span> <span class="o">*</span><span class="n">n</span><span class="p">;</span>
  <span class="n">perrdetail</span> <span class="n">e</span><span class="p">;</span>

  <span class="n">n</span> <span class="o">=</span> <span class="n">PyParser_ParseString</span><span class="p">(</span><span class="n">code</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">_PyParser_Grammar</span><span class="p">,</span>
                           <span class="n">Py_file_input</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">e</span><span class="p">);</span>
  <span class="k">if</span> <span class="p">(</span><span class="n">n</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">e</span><span class="p">.</span><span class="n">error</span> <span class="o">==</span> <span class="n">E_EOF</span><span class="p">)</span>
      <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
    <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
  <span class="p">}</span>

  <span class="n">PyNode_Free</span><span class="p">(</span><span class="n">n</span><span class="p">);</span>
  <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>另一个解决方案是尝试使用 <a class="reference internal" href="../c-api/veryhigh.html#c.Py_CompileString" title="Py_CompileString"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_CompileString()</span></code></a> 编译接收到的字符串。如果编译时没有出现错误，请尝试通过调用 <a class="reference internal" href="../c-api/veryhigh.html#c.PyEval_EvalCode" title="PyEval_EvalCode"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyEval_EvalCode()</span></code></a> 来执行返回的代码对象。否则，请将输入保存到以后。如果编译失败，找出是错误还是只需要更多的输入-从异常元组中提取消息字符串，并将其与字符串 “分析时意外的EOF” 进行比较。下面是使用GNUreadline库的完整示例(您可能希望在调用readline()时忽略 <strong>SIGINT</strong> )：</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;readline.h&gt;</span><span class="cp"></span>

<span class="cp">#define PY_SSIZE_T_CLEAN</span>
<span class="cp">#include</span> <span class="cpf">&lt;Python.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;object.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;compile.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;eval.h&gt;</span><span class="cp"></span>

<span class="kt">int</span> <span class="nf">main</span> <span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span><span class="o">*</span> <span class="n">argv</span><span class="p">[])</span>
<span class="p">{</span>
  <span class="kt">int</span> <span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">done</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>                          <span class="cm">/* lengths of line, code */</span>
  <span class="kt">char</span> <span class="n">ps1</span><span class="p">[]</span> <span class="o">=</span> <span class="s">&quot;&gt;&gt;&gt; &quot;</span><span class="p">;</span>
  <span class="kt">char</span> <span class="n">ps2</span><span class="p">[]</span> <span class="o">=</span> <span class="s">&quot;... &quot;</span><span class="p">;</span>
  <span class="kt">char</span> <span class="o">*</span><span class="n">prompt</span> <span class="o">=</span> <span class="n">ps1</span><span class="p">;</span>
  <span class="kt">char</span> <span class="o">*</span><span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">line</span><span class="p">,</span> <span class="o">*</span><span class="n">code</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
  <span class="n">PyObject</span> <span class="o">*</span><span class="n">src</span><span class="p">,</span> <span class="o">*</span><span class="n">glb</span><span class="p">,</span> <span class="o">*</span><span class="n">loc</span><span class="p">;</span>
  <span class="n">PyObject</span> <span class="o">*</span><span class="n">exc</span><span class="p">,</span> <span class="o">*</span><span class="n">val</span><span class="p">,</span> <span class="o">*</span><span class="n">trb</span><span class="p">,</span> <span class="o">*</span><span class="n">obj</span><span class="p">,</span> <span class="o">*</span><span class="n">dum</span><span class="p">;</span>

  <span class="n">Py_Initialize</span> <span class="p">();</span>
  <span class="n">loc</span> <span class="o">=</span> <span class="n">PyDict_New</span> <span class="p">();</span>
  <span class="n">glb</span> <span class="o">=</span> <span class="n">PyDict_New</span> <span class="p">();</span>
  <span class="n">PyDict_SetItemString</span> <span class="p">(</span><span class="n">glb</span><span class="p">,</span> <span class="s">&quot;__builtins__&quot;</span><span class="p">,</span> <span class="n">PyEval_GetBuiltins</span> <span class="p">());</span>

  <span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="n">done</span><span class="p">)</span>
  <span class="p">{</span>
    <span class="n">line</span> <span class="o">=</span> <span class="n">readline</span> <span class="p">(</span><span class="n">prompt</span><span class="p">);</span>

    <span class="k">if</span> <span class="p">(</span><span class="nb">NULL</span> <span class="o">==</span> <span class="n">line</span><span class="p">)</span>                          <span class="cm">/* Ctrl-D pressed */</span>
    <span class="p">{</span>
      <span class="n">done</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="k">else</span>
    <span class="p">{</span>
      <span class="n">i</span> <span class="o">=</span> <span class="n">strlen</span> <span class="p">(</span><span class="n">line</span><span class="p">);</span>

      <span class="k">if</span> <span class="p">(</span><span class="n">i</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span>
        <span class="n">add_history</span> <span class="p">(</span><span class="n">line</span><span class="p">);</span>                    <span class="cm">/* save non-empty lines */</span>

      <span class="k">if</span> <span class="p">(</span><span class="nb">NULL</span> <span class="o">==</span> <span class="n">code</span><span class="p">)</span>                        <span class="cm">/* nothing in code yet */</span>
        <span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
      <span class="k">else</span>
        <span class="n">j</span> <span class="o">=</span> <span class="n">strlen</span> <span class="p">(</span><span class="n">code</span><span class="p">);</span>

      <span class="n">code</span> <span class="o">=</span> <span class="n">realloc</span> <span class="p">(</span><span class="n">code</span><span class="p">,</span> <span class="n">i</span> <span class="o">+</span> <span class="n">j</span> <span class="o">+</span> <span class="mi">2</span><span class="p">);</span>
      <span class="k">if</span> <span class="p">(</span><span class="nb">NULL</span> <span class="o">==</span> <span class="n">code</span><span class="p">)</span>                        <span class="cm">/* out of memory */</span>
        <span class="n">exit</span> <span class="p">(</span><span class="mi">1</span><span class="p">);</span>

      <span class="k">if</span> <span class="p">(</span><span class="mi">0</span> <span class="o">==</span> <span class="n">j</span><span class="p">)</span>                              <span class="cm">/* code was empty, so */</span>
        <span class="n">code</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="sc">&#39;\0&#39;</span><span class="p">;</span>                        <span class="cm">/* keep strncat happy */</span>

      <span class="n">strncat</span> <span class="p">(</span><span class="n">code</span><span class="p">,</span> <span class="n">line</span><span class="p">,</span> <span class="n">i</span><span class="p">);</span>                 <span class="cm">/* append line to code */</span>
      <span class="n">code</span><span class="p">[</span><span class="n">i</span> <span class="o">+</span> <span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="sc">&#39;\n&#39;</span><span class="p">;</span>                      <span class="cm">/* append &#39;\n&#39; to code */</span>
      <span class="n">code</span><span class="p">[</span><span class="n">i</span> <span class="o">+</span> <span class="n">j</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="sc">&#39;\0&#39;</span><span class="p">;</span>

      <span class="n">src</span> <span class="o">=</span> <span class="n">Py_CompileString</span> <span class="p">(</span><span class="n">code</span><span class="p">,</span> <span class="s">&quot;&lt;stdin&gt;&quot;</span><span class="p">,</span> <span class="n">Py_single_input</span><span class="p">);</span>

      <span class="k">if</span> <span class="p">(</span><span class="nb">NULL</span> <span class="o">!=</span> <span class="n">src</span><span class="p">)</span>                         <span class="cm">/* compiled just fine - */</span>
      <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">ps1</span>  <span class="o">==</span> <span class="n">prompt</span> <span class="o">||</span>                  <span class="cm">/* &quot;&gt;&gt;&gt; &quot; or */</span>
            <span class="sc">&#39;\n&#39;</span> <span class="o">==</span> <span class="n">code</span><span class="p">[</span><span class="n">i</span> <span class="o">+</span> <span class="n">j</span> <span class="o">-</span> <span class="mi">1</span><span class="p">])</span>           <span class="cm">/* &quot;... &quot; and double &#39;\n&#39; */</span>
        <span class="p">{</span>                                               <span class="cm">/* so execute it */</span>
          <span class="n">dum</span> <span class="o">=</span> <span class="n">PyEval_EvalCode</span> <span class="p">(</span><span class="n">src</span><span class="p">,</span> <span class="n">glb</span><span class="p">,</span> <span class="n">loc</span><span class="p">);</span>
          <span class="n">Py_XDECREF</span> <span class="p">(</span><span class="n">dum</span><span class="p">);</span>
          <span class="n">Py_XDECREF</span> <span class="p">(</span><span class="n">src</span><span class="p">);</span>
          <span class="n">free</span> <span class="p">(</span><span class="n">code</span><span class="p">);</span>
          <span class="n">code</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
          <span class="k">if</span> <span class="p">(</span><span class="n">PyErr_Occurred</span> <span class="p">())</span>
            <span class="n">PyErr_Print</span> <span class="p">();</span>
          <span class="n">prompt</span> <span class="o">=</span> <span class="n">ps1</span><span class="p">;</span>
        <span class="p">}</span>
      <span class="p">}</span>                                        <span class="cm">/* syntax error or E_EOF? */</span>
      <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">PyErr_ExceptionMatches</span> <span class="p">(</span><span class="n">PyExc_SyntaxError</span><span class="p">))</span>
      <span class="p">{</span>
        <span class="n">PyErr_Fetch</span> <span class="p">(</span><span class="o">&amp;</span><span class="n">exc</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">val</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">trb</span><span class="p">);</span>        <span class="cm">/* clears exception! */</span>

        <span class="k">if</span> <span class="p">(</span><span class="n">PyArg_ParseTuple</span> <span class="p">(</span><span class="n">val</span><span class="p">,</span> <span class="s">&quot;sO&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">msg</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">obj</span><span class="p">)</span> <span class="o">&amp;&amp;</span>
            <span class="o">!</span><span class="n">strcmp</span> <span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="s">&quot;unexpected EOF while parsing&quot;</span><span class="p">))</span> <span class="cm">/* E_EOF */</span>
        <span class="p">{</span>
          <span class="n">Py_XDECREF</span> <span class="p">(</span><span class="n">exc</span><span class="p">);</span>
          <span class="n">Py_XDECREF</span> <span class="p">(</span><span class="n">val</span><span class="p">);</span>
          <span class="n">Py_XDECREF</span> <span class="p">(</span><span class="n">trb</span><span class="p">);</span>
          <span class="n">prompt</span> <span class="o">=</span> <span class="n">ps2</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="k">else</span>                                   <span class="cm">/* some other syntax error */</span>
        <span class="p">{</span>
          <span class="n">PyErr_Restore</span> <span class="p">(</span><span class="n">exc</span><span class="p">,</span> <span class="n">val</span><span class="p">,</span> <span class="n">trb</span><span class="p">);</span>
          <span class="n">PyErr_Print</span> <span class="p">();</span>
          <span class="n">free</span> <span class="p">(</span><span class="n">code</span><span class="p">);</span>
          <span class="n">code</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
          <span class="n">prompt</span> <span class="o">=</span> <span class="n">ps1</span><span class="p">;</span>
        <span class="p">}</span>
      <span class="p">}</span>
      <span class="k">else</span>                                     <span class="cm">/* some non-syntax error */</span>
      <span class="p">{</span>
        <span class="n">PyErr_Print</span> <span class="p">();</span>
        <span class="n">free</span> <span class="p">(</span><span class="n">code</span><span class="p">);</span>
        <span class="n">code</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
        <span class="n">prompt</span> <span class="o">=</span> <span class="n">ps1</span><span class="p">;</span>
      <span class="p">}</span>

      <span class="n">free</span> <span class="p">(</span><span class="n">line</span><span class="p">);</span>
    <span class="p">}</span>
  <span class="p">}</span>

  <span class="n">Py_XDECREF</span><span class="p">(</span><span class="n">glb</span><span class="p">);</span>
  <span class="n">Py_XDECREF</span><span class="p">(</span><span class="n">loc</span><span class="p">);</span>
  <span class="n">Py_Finalize</span><span class="p">();</span>
  <span class="n">exit</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="how-do-i-find-undefined-g-symbols-builtin-new-or-pure-virtual">
<h2><a class="toc-backref" href="#id19">如何找到未定义的g++符号__builtin_new或__pure_virtual？</a><a class="headerlink" href="#how-do-i-find-undefined-g-symbols-builtin-new-or-pure-virtual" title="永久链接至标题">¶</a></h2>
<p>要动态加载g ++扩展模块，必须重新编译Python，要使用g ++重新链接（在Python Modules Makefile中更改LINKCC），及链接扩展模块（例如： <code class="docutils literal notranslate"><span class="pre">g++</span> <span class="pre">-shared</span> <span class="pre">-o</span> <span class="pre">mymodule.so</span> <span class="pre">mymodule.o</span></code> ）。</p>
</div>
<div class="section" id="can-i-create-an-object-class-with-some-methods-implemented-in-c-and-others-in-python-e-g-through-inheritance">
<h2><a class="toc-backref" href="#id20">能否创建一个对象类，其中部分方法在C中实现，而其他方法在Python中实现（例如通过继承）？</a><a class="headerlink" href="#can-i-create-an-object-class-with-some-methods-implemented-in-c-and-others-in-python-e-g-through-inheritance" title="永久链接至标题">¶</a></h2>
<p>是的，您可以继承内置类，例如 <a class="reference internal" href="../library/functions.html#int" title="int"><code class="xref py py-class docutils literal notranslate"><span class="pre">int</span></code></a> ， <a class="reference internal" href="../library/stdtypes.html#list" title="list"><code class="xref py py-class docutils literal notranslate"><span class="pre">list</span></code></a> ， <a class="reference internal" href="../library/stdtypes.html#dict" title="dict"><code class="xref py py-class docutils literal notranslate"><span class="pre">dict</span></code></a> 等。</p>
<p>Boost Python库（BPL，http：//www.boost.org/libs/python/doc/index.html）提供了一种从C ++执行此操作的方法（即，您可以使用BPL继承自C ++编写的扩展类 ）。</p>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
  <h3><a href="../contents.html">目录</a></h3>
  <ul>
<li><a class="reference internal" href="#">扩展/嵌入常见问题</a><ul>
<li><a class="reference internal" href="#can-i-create-my-own-functions-in-c">可以使用C语言中创建自己的函数吗？</a></li>
<li><a class="reference internal" href="#id2">可以使用C++语言中创建自己的函数吗？</a></li>
<li><a class="reference internal" href="#writing-c-is-hard-are-there-any-alternatives">C很难写，有没有其他选择？</a></li>
<li><a class="reference internal" href="#how-can-i-execute-arbitrary-python-statements-from-c">如何在 C 中执行任意 Python 语句？</a></li>
<li><a class="reference internal" href="#how-can-i-evaluate-an-arbitrary-python-expression-from-c">如何在 C 中对任意 Python 表达式求值？</a></li>
<li><a class="reference internal" href="#how-do-i-extract-c-values-from-a-python-object">如何从Python对象中提取C的值？</a></li>
<li><a class="reference internal" href="#how-do-i-use-py-buildvalue-to-create-a-tuple-of-arbitrary-length">如何使用Py_BuildValue()创建任意长度的元组？</a></li>
<li><a class="reference internal" href="#how-do-i-call-an-object-s-method-from-c">如何从C调用对象的方法？</a></li>
<li><a class="reference internal" href="#how-do-i-catch-the-output-from-pyerr-print-or-anything-that-prints-to-stdout-stderr">如何捕获PyErr_Print()（或打印到stdout / stderr的任何内容）的输出？</a></li>
<li><a class="reference internal" href="#how-do-i-access-a-module-written-in-python-from-c">如何从C访问用Python编写的模块？</a></li>
<li><a class="reference internal" href="#how-do-i-interface-to-c-objects-from-python">如何在 Python 中对接 C ++ 对象？</a></li>
<li><a class="reference internal" href="#i-added-a-module-using-the-setup-file-and-the-make-fails-why">我使用Setup文件添加了一个模块，为什么make失败了？</a></li>
<li><a class="reference internal" href="#how-do-i-debug-an-extension">如何调试扩展？</a></li>
<li><a class="reference internal" href="#i-want-to-compile-a-python-module-on-my-linux-system-but-some-files-are-missing-why">我想在Linux系统上编译一个Python模块，但是缺少一些文件。为什么?</a></li>
<li><a class="reference internal" href="#how-do-i-tell-incomplete-input-from-invalid-input">如何区分“输入不完整”和“输入无效”？</a></li>
<li><a class="reference internal" href="#how-do-i-find-undefined-g-symbols-builtin-new-or-pure-virtual">如何找到未定义的g++符号__builtin_new或__pure_virtual？</a></li>
<li><a class="reference internal" href="#can-i-create-an-object-class-with-some-methods-implemented-in-c-and-others-in-python-e-g-through-inheritance">能否创建一个对象类，其中部分方法在C中实现，而其他方法在Python中实现（例如通过继承）？</a></li>
</ul>
</li>
</ul>

  <h4>上一个主题</h4>
  <p class="topless"><a href="library.html"
                        title="上一章">代码库和插件 FAQ</a></p>
  <h4>下一个主题</h4>
  <p class="topless"><a href="windows.html"
                        title="下一章">Python在Windows上的常见问题</a></p>
  <div role="note" aria-label="source link">
    <h3>本页</h3>
    <ul class="this-page-menu">
      <li><a href="../bugs.html">提交 Bug</a></li>
      <li>
        <a href="https://github.com/python/cpython/blob/3.7/Doc/faq/extending.rst"
            rel="nofollow">显示源代码
        </a>
      </li>
    </ul>
  </div>
        </div>
      </div>
      <div class="clearer"></div>
    </div>  
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>导航</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="总目录"
             >索引</a></li>
        <li class="right" >
          <a href="../py-modindex.html" title="Python 模块索引"
             >模块</a> |</li>
        <li class="right" >
          <a href="windows.html" title="Python在Windows上的常见问题"
             >下一页</a> |</li>
        <li class="right" >
          <a href="library.html" title="代码库和插件 FAQ"
             >上一页</a> |</li>
        <li><img src="../_static/py.png" alt=""
                 style="vertical-align: middle; margin-top: -1px"/></li>
        <li><a href="https://www.python.org/">Python</a> &#187;</li>
        <li>
          <a href="../index.html">3.7.8 Documentation</a> &#187;
        </li>

          <li class="nav-item nav-item-1"><a href="index.html" >Python 常见问题</a> &#187;</li>
    <li class="right">
        

    <div class="inline-search" style="display: none" role="search">
        <form class="inline-search" action="../search.html" method="get">
          <input placeholder="快速搜索" type="text" name="q" />
          <input type="submit" value="转向" />
          <input type="hidden" name="check_keywords" value="yes" />
          <input type="hidden" name="area" value="default" />
        </form>
    </div>
    <script type="text/javascript">$('.inline-search').show(0);</script>
         |
    </li>

      </ul>
    </div>  
    <div class="footer">
    &copy; <a href="../copyright.html">版权所有</a> 2001-2020, Python Software Foundation.
    <br />
    Python 软件基金会是一个非盈利组织。
    <a href="https://www.python.org/psf/donations/">请捐助。</a>
    <br />
    最后更新于 6月 29, 2020.
    <a href="../bugs.html">发现了问题</a>？
    <br />
    使用<a href="http://sphinx.pocoo.org/">Sphinx</a>2.3.1 创建。
    </div>

  </body>
</html>